
/**
  ******************************************************************************
  * Copyright 2021 The Microbee Authors. All Rights Reserved.
  * 
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
  * You may obtain a copy of the License at
  * 
  * http://www.apache.org/licenses/LICENSE-2.0
  * 
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  * See the License for the specific language governing permissions and
  * limitations under the License.
  * 
  * @file       analogin_backend.h
  * @author     baiyang
  * @date       2022-10-24
  ******************************************************************************
  */

#pragma once

#ifdef __cplusplus
extern "C"{
#endif

/*----------------------------------include-----------------------------------*/
#include <rtthread.h>

#include <stdint.h>
#include <stdbool.h>
/*-----------------------------------macro------------------------------------*/
#define ANALOG_INPUT_BOARD_VCC 254
#define ANALOG_INPUT_NONE 255
/*----------------------------------typedef-----------------------------------*/
typedef struct AnalogSourceBackend* analog_source_backend_t;

struct AnalogSourceBackend {
    struct AnalogSourceBackendOps *ops;
};

struct AnalogSourceBackendOps
{
    float (*read_average)   (analog_source_backend_t analog_source_backend);
    float (*read_latest)    (analog_source_backend_t analog_source_backend);
    bool  (*set_pin)        (analog_source_backend_t analog_source_backend, uint8_t p);

    // return a voltage from 0.0 to 5.0V, scaled
    // against a reference voltage
    float (*voltage_average)(analog_source_backend_t analog_source_backend);

    // return a voltage from 0.0 to 5.0V, scaled
    // against a reference voltage
    float (*voltage_latest) (analog_source_backend_t analog_source_backend);

    // return a voltage from 0.0 to 5.0V, assuming a ratiometric
    // sensor
    float (*voltage_average_ratiometric)(analog_source_backend_t analog_source_backend);
};

/*----------------------------------variable----------------------------------*/

/*-------------------------------------os-------------------------------------*/

/*----------------------------------function----------------------------------*/
static inline float analogsource_read_average(analog_source_backend_t analog_source_backend) {
    RT_ASSERT(analog_source_backend != RT_NULL);
    RT_ASSERT(analog_source_backend->ops != RT_NULL);
    RT_ASSERT(analog_source_backend->ops->read_average != RT_NULL);

    return analog_source_backend->ops->read_average(analog_source_backend);
}

static inline float analogsource_read_latest(analog_source_backend_t analog_source_backend) {
    RT_ASSERT(analog_source_backend != RT_NULL);
    RT_ASSERT(analog_source_backend->ops != RT_NULL);
    RT_ASSERT(analog_source_backend->ops->read_latest != RT_NULL);

    return analog_source_backend->ops->read_latest(analog_source_backend);
}

static inline bool analogsource_set_pin(analog_source_backend_t analog_source_backend, uint8_t p) {
    RT_ASSERT(analog_source_backend != RT_NULL);
    RT_ASSERT(analog_source_backend->ops != RT_NULL);
    RT_ASSERT(analog_source_backend->ops->set_pin != RT_NULL);

    return analog_source_backend->ops->set_pin(analog_source_backend, p);
}

// return a voltage from 0.0 to 5.0V, scaled
// against a reference voltage
static inline float analogsource_voltage_average(analog_source_backend_t analog_source_backend) {
    RT_ASSERT(analog_source_backend != RT_NULL);
    RT_ASSERT(analog_source_backend->ops != RT_NULL);
    RT_ASSERT(analog_source_backend->ops->voltage_average != RT_NULL);

    return analog_source_backend->ops->voltage_average(analog_source_backend);
}

// return a voltage from 0.0 to 5.0V, scaled
// against a reference voltage
static inline float analogsource_voltage_latest(analog_source_backend_t analog_source_backend) {
    RT_ASSERT(analog_source_backend != RT_NULL);
    RT_ASSERT(analog_source_backend->ops != RT_NULL);
    RT_ASSERT(analog_source_backend->ops->voltage_latest != RT_NULL);

    return analog_source_backend->ops->voltage_latest(analog_source_backend);
}

// return a voltage from 0.0 to 5.0V, assuming a ratiometric
// sensor
static inline float analogsource_voltage_average_ratiometric(analog_source_backend_t analog_source_backend) {
    RT_ASSERT(analog_source_backend != RT_NULL);
    RT_ASSERT(analog_source_backend->ops != RT_NULL);
    RT_ASSERT(analog_source_backend->ops->voltage_average_ratiometric != RT_NULL);

    return analog_source_backend->ops->voltage_average_ratiometric(analog_source_backend);
}

/*------------------------------------test------------------------------------*/

#ifdef __cplusplus
}
#endif



